package peer.SharingManager;

import java.io.DataInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

import peer.NetworkManager.NetworkManager;
import peer.SearchManager.SearchManager;
import peer.gui.PeerGUI;

import common.Packet;

public class Downloader extends Thread
{
	private PeerGUI PeerGui = PeerGUI.instance();
	private NetworkManager nm = NetworkManager.instance();
	
	String name;
	long size;
	String hashCode;
	
	public Downloader(String name, long size, String hashcode)
	{
		this.name = name;
		this.size = size;
		this.hashCode = hashcode;
		this.start();
	}

	public void run()
	{
		System.out.println("downloader thread running!!!!!!!!!");
		try
		{
			//add peers to gui
			SearchManager sm = SearchManager.instance();
			for (int i = 0; i < sm.getPeerCount(); i++)
			{
				InetSocketAddress peer = sm.getPeer(i);
				PeerGui.addPeer(peer.getAddress().getHostAddress(), peer.getPort(), 100);
			}
			
			InetSocketAddress peer = SearchManager.instance().getPeer(0);
			PeerGui.writeLog("downloading " + name + " from " + peer.getAddress().getHostAddress() + ":" + peer.getPort());
			ServerSocket listener = new ServerSocket(0);
			//BufferedWriter out = new BufferedWriter(new FileWriter("file" + System.currentTimeMillis() + ".txt"));
			FileOutputStream out = new FileOutputStream("file" + System.currentTimeMillis() + ".txt");
			int numberOfBlocks = (int) (size / (16 * 1024));
			if(size % (16 * 1024) != 0)
			{
				numberOfBlocks++;
			}
			for(int block = 0; block < numberOfBlocks; block++)
			{
				//send a UDP packet requesting the block
				Packet p = new Packet(Packet.Type.request_block);
				p.addHeader("name", name);
				p.addHeader("file_size", Long.toString(size));
				p.addHeader("hash_code", hashCode);
				p.addHeader("block", Integer.toString(block));
				p.addHeader("port", Integer.toString(listener.getLocalPort()));
				PeerGui.writeLog("requesting block " + block);
				nm.sendPeerPacket(p, peer);
				//receive the block
				Socket socket = listener.accept();
				//BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				DataInputStream in = new DataInputStream(socket.getInputStream());
				
				//and write it to a file
				int next = in.read();
				while(next != -1)
				{
					/*if(next > 127)
					{
						next = -256 + next;
					*/
					out.write(next);
					next = in.read();
				}
				in.close();
				socket.close();
				PeerGui.completedBlock(block);
				PeerGui.writeLog("received block " + block);
				
			}
			out.close();
		} catch (IOException e)
		{
			e.printStackTrace();
		}
	}
	
	
}
